﻿using Library.Collections.Specialized;
using Library.Linq;
using Library.Logic.Inference;
using System.Collections.Generic;
using TRULE = System.Linq.Expressions.Expression<System.Func<System.Linq.IQueryable<System.Linq.Expressions.Expression>, System.Collections.Generic.IEnumerable<System.Collections.Generic.IEnumerable<System.Linq.Expressions.Expression>>>>;
using TEXPRESSION = System.Linq.Expressions.Expression;

namespace Library.Logic
{
    public static partial class Builtin
    {
        //public static System.Linq.IQueryable<T> Reason<T>(this IReasonerReadOnly<T> reasoner, System.Linq.IQueryable<T> input)
        //{
        //    return reasoner.Provider.CreateQuery<T>(
        //        Expression.Call(null, (System.Reflection.MethodInfo)MethodInfo.GetCurrentMethod(), Expression.Constant(reasoner), input.Expression)
        //    );
        //}

        public static bool Contains<T>(this IEnumerable<T> enumerable, T item, out IInference argument)
        {
            IContainerReason<T> containerReason = enumerable as IContainerReason<T>;
            if (containerReason != null)
            {
                return containerReason.Contains(item, out argument);
            }
            else
            {
                argument = Builtin.Inference();
                return enumerable.Contains(item);
            }
        }
        public static bool ContainsAll<T>(this IEnumerable<T> enumerable, IEnumerable<T> items, out IInference argument)
        {
            IContainerBulkReason<T> containerReason = enumerable as IContainerBulkReason<T>;
            if (containerReason != null)
            {
                return containerReason.ContainsAll(items, out argument);
            }
            else
            {
                argument = Builtin.Inference();
                return enumerable.ContainsAll(items);
            }
        }

        //public static bool Contains<T>(this System.Linq.IQueryable<T> queryable, T item, out IArgument argument)
        //{
        //    IContainerReason<T> containerReason = queryable as IContainerReason<T>;
        //    if (containerReason != null)
        //    {
        //        return containerReason.Contains(item, out argument);
        //    }
        //    else
        //    {
        //        argument = Builtin.Claim();
        //        return queryable.Contains(item);
        //    }
        //}
        //public static bool ContainsAll<T>(this System.Linq.IQueryable<T> queryable, IEnumerable<T> items, out IArgument argument)
        //{
        //    IContainerBulkReason<T> containerReason = queryable as IContainerBulkReason<T>;
        //    if (containerReason != null)
        //    {
        //        return containerReason.ContainsAll(items, out argument);
        //    }
        //    else
        //    {
        //        argument = Builtin.Claim();
        //        return queryable.ContainsAll(items.AsQueryable());
        //    }
        //}
        //public static bool ContainsAll<T>(this System.Linq.IQueryable<T> queryable, System.Linq.IQueryable<T> items, out IArgument argument)
        //{
        //    IContainerBulkReason<T> containerReason = queryable as IContainerBulkReason<T>;
        //    if (containerReason != null)
        //    {
        //        return containerReason.ContainsAll(items, out argument);
        //    }
        //    else
        //    {
        //        argument = Builtin.Claim();
        //        return queryable.ContainsAll(items);
        //    }
        //}

        public static bool Entails(this System.Linq.IQueryable<TEXPRESSION> source, TEXPRESSION item, IReasonerReadOnly<TEXPRESSION> reasoner)
        {
            return reasoner.Reason(source).Contains(item);
        }
        public static bool Entails(this System.Linq.IQueryable<TEXPRESSION> source, System.Linq.IQueryable<TEXPRESSION> items, IReasonerReadOnly<TEXPRESSION> reasoner)
        {
            return reasoner.Reason(source).ContainsAll(items);
        }
        public static bool Entails(this System.Linq.IQueryable<TEXPRESSION> source, TEXPRESSION item, IReasonerReadOnly<TEXPRESSION, TRULE> reasoner, out IInference argument)
        {
            return reasoner.Reason(source).Contains(item, out argument);
        }
        public static bool Entails(this System.Linq.IQueryable<TEXPRESSION> source, System.Linq.IQueryable<TEXPRESSION> items, IReasonerReadOnly<TEXPRESSION, TRULE> reasoner, out IInference argument)
        {
            return reasoner.Reason(source).ContainsAll(items, out argument);
        }
    }
}
